{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "\n",
    "# DAC-ADC Pmod Examples using Matplotlib and Widget\n",
    "\n",
    "----\n",
    "\n",
    "## Contents\n",
    "\n",
    "\n",
    "[Pmod DAC-ADC Feedback](#Pmod-DAC-ADC-Feedback)\n",
    "\n",
    "[Tracking the IO Error](#Tracking-the-IO-Error)\n",
    "\n",
    "[Error plot with Matplotlib](#Error-plot-with-Matplotlib)\n",
    "\n",
    "[Widget controlled plot](#Widget-controlled-plot)\n",
    "\n",
    "----\n",
    "\n",
    "## Pmod DAC-ADC Feedback\n",
    "\n",
    "This example shows how to use the PmodDA4 DAC and the PmodAD2 ADC on the board, using the board's two Pmod interfaces. The notebook then compares the DAC output to the ADC input and tracks the errors.\n",
    "\n",
    "The errors are plotted using Matplotlib and an XKCD version of the plot is produced (for fun). Finally a slider widget is introduced to control the number of samples diaplayed in the error plot.\n",
    "\n",
    "Note: The output of the DAC (pin A) must be connected with a wire to the input of the ADC (V1 input).\n",
    "\n",
    "### 1. Import hardware libraries and classes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "\n",
       "require(['notebook/js/codecell'], function(codecell) {\n",
       "  codecell.CodeCell.options_default.highlight_modes[\n",
       "      'magic_text/x-csrc'] = {'reg':[/^%%microblaze/]};\n",
       "  Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n",
       "      Jupyter.notebook.get_cells().map(function(cell){\n",
       "          if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n",
       "  });\n",
       "});\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from pynq.overlays.base import BaseOverlay\n",
    "from pynq.lib import Pmod_ADC, Pmod_DAC"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. Program the ZYNQ PL"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "ol = BaseOverlay(\"base.bit\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. Instantiate the Pmod peripherals as Python objects"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "dac = Pmod_DAC(ol.PMODB)\n",
    "adc = Pmod_ADC(ol.PMODA)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4. Write to DAC, read from ADC, print result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.3418]\n"
     ]
    }
   ],
   "source": [
    "dac.write(0.35)\n",
    "sample = adc.read()\n",
    "print(sample)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----\n",
    "\n",
    "[Contents](#Contents)\n",
    "\n",
    "----"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Tracking the IO Error\n",
    "Report DAC-ADC Pmod Loopback Measurement Error."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Value written: 0.00\tSample read: 0.00\tError: +0.0015\n",
      "Value written: 0.11\tSample read: 0.10\tError: -0.0037\n",
      "Value written: 0.21\tSample read: 0.21\tError: +0.0004\n",
      "Value written: 0.32\tSample read: 0.31\tError: -0.0072\n",
      "Value written: 0.42\tSample read: 0.43\tError: +0.0086\n",
      "Value written: 0.53\tSample read: 0.50\tError: -0.0278\n",
      "Value written: 0.63\tSample read: 0.62\tError: -0.0144\n",
      "Value written: 0.74\tSample read: 0.71\tError: -0.0220\n",
      "Value written: 0.84\tSample read: 0.81\tError: -0.0335\n",
      "Value written: 0.95\tSample read: 0.93\tError: -0.0177\n",
      "Value written: 1.05\tSample read: 1.03\tError: -0.0253\n",
      "Value written: 1.16\tSample read: 1.12\tError: -0.0368\n",
      "Value written: 1.26\tSample read: 1.21\tError: -0.0484\n",
      "Value written: 1.37\tSample read: 1.31\tError: -0.0598\n",
      "Value written: 1.47\tSample read: 1.43\tError: -0.0401\n",
      "Value written: 1.58\tSample read: 1.53\tError: -0.0516\n",
      "Value written: 1.68\tSample read: 1.62\tError: -0.0631\n",
      "Value written: 1.79\tSample read: 1.72\tError: -0.0727\n",
      "Value written: 1.89\tSample read: 1.81\tError: -0.0842\n",
      "Value written: 2.00\tSample read: 1.93\tError: -0.0664\n"
     ]
    }
   ],
   "source": [
    "from math import ceil\n",
    "from time import sleep\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from pynq.lib import Pmod_ADC, Pmod_DAC\n",
    "from pynq.overlays.base import BaseOverlay\n",
    "\n",
    "ol = BaseOverlay(\"base.bit\")\n",
    "\n",
    "dac = Pmod_DAC(ol.PMODB)\n",
    "adc = Pmod_ADC(ol.PMODA)\n",
    "\n",
    "delay = 0.0\n",
    "values = np.linspace(0, 2, 20)\n",
    "samples = []\n",
    "for value in values:\n",
    "    dac.write(value)\n",
    "    sleep(delay)\n",
    "    sample = adc.read()\n",
    "    samples.append(sample[0])\n",
    "    print('Value written: {:4.2f}\\tSample read: {:4.2f}\\tError: {:+4.4f}'.\n",
    "          format(value, sample[0], sample[0]-value))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----\n",
    "\n",
    "[Contents](#Contents)\n",
    "\n",
    "----"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Error plot with Matplotlib\n",
    "This example shows plots in notebook (rather than in separate window)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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mbJN/R31ne98Z7vX7dSpE4MGDaJ///4MHDiQW265hS1btmxV5wtf+AI9e/bcpvyhhx6iurqaww8/nH79+vGVr3xlu+Mw25mU+2e0tf5RzT1hSOpCMjrXFyPinYaLi6wSZcq3LYwYFxHVEVHdo0em7lBa1DHHHMOTTz4JwJYtW1i5ciVz586tX/7kk09y7LHH1s9v3ry5vhzaR8L40Ic+RG1tLXPnzuWRRx5hypQpfPOb36xfvmXLFiZPnkyvXr147LG/9Yg9Z84cRo8ezb333su8efOYM2cOH/5ww9FAzTqmcv/cNvaPal5yTRiSdiNJFr+KiGJDOS4BehXMHwQsLVPe7hx77LH1X/5z586lsrKSvfbai7fffpuNGzcyb9481qxZw0knncRnP/tZjjzySAC6dOkCwDXXXMPjjz/OoEGD+N73vseYMWOYNGkSgwYNYtKkSbz33ntceumlDBkyhKqqKv7whz8AcNddd3HeeecxYsQI+vbty9VXX10yxmuuuYb169czaNAgLrroIgBuueUWKisrqays3OoMqTH7778/48aN4/bbb6eu6/zp06dTWVnJ5z73OSZMmFBf9/vf/z7XXXcd/fr1A2DXXXfl85//fOZ9mVkLi4hcJpKzhLuB28rUORN4KK17NPCXtLw78ArQLZ1eAbo3ts+jjjoqsoDmm7I45JBD4tVXX4077rgjfvrTn8bXv/71+OMf/xhPPPFEHHfccTF9+vTYc889Y9GiRfXrdO7cOSIipk+fHmeeeWZ9+Z133hlXXXVV/fy1114b99xzT0REvP3229G3b99Yu3Zt3HnnndGnT59YvXp1rF+/Pg4++OD461//WjLGuv1FRNTU1ERlZWWsXbs23n333TjiiCPiueeey7RunX322SfeeOONiIi47LLL4u677441a9bEgQceGO+//35ERFRVVUVtbW3ZY2fWke3I9072fVATGb/X8zzDOJZkCMd/lFSbTmdIulLSlWmdKcAikoHrfw58Pk1iq4CbgGfT6ca0rF2qO8t48sknGT58OMOHD6+fr7tWMXToUPr06dPkbU+dOpXvfve7DBo0iBNPPJENGzbw17/+FYCTTz6Zrl27UlFRwRFHHMGrr2brlPKJJ57g3HPPpXPnznTp0oXzzjuPxx9/vElxRXp28f777zNlyhTOOecc9t57b4YNG8bUqVOb9ibNrE3I7bbaiHiC4tciCusEcFWJZeOB8TmE1uLqrmPMnj2byspKevXqxQ9/+EP23ntvLr30UgA6d+68XduOCH77299y2GGHbVX+zDPPsMcee9TPd+rUiU2bNmXe5o5YtGgRnTp1Yv/99+eBBx5gzZo19U1t69atY8899+TMM8+kf//+zJgxg4EDB+7Q/sysZXS4J703bGjOBqlsdysce+yxPPjgg3Tv3p1OnTrRvXt3Vq9ezVNPPcXw4cPLrrvXXnvx7rvvlpw//fTT+dGPflT/JT9z5sztOi677bYbH3zwAQDHH388v//971m3bh3vvfcekydP5rjjjsu0nRUrVnDllVcyevRoJDFhwgR+8YtfsHjxYhYvXswrr7zC1KlTWbduHV/96lf5zne+w0svvQQkF8eL3TFmZm1Dh0sYzX13QZbtHXnkkaxcuZKjjz56q7KuXbuy3377lV13wIAB7LrrrgwcOJBbb72Vk046iRdeeKH+ovc3vvENPvjgAwYMGEBlZSXf+MY3tut9jBo1igEDBnDRRRcxePBgLrnkEoYOHcqwYcO4/PLLqaqqKrlu3QXz/v37c8opp3Daaadx/fXXs27dOh5++GHOPPPM+rqdO3fmox/9KA888AADBgzgtttu48ILL+Twww+nsrKSZcuWbVf8ZjuzZa9s2Oof1W200H222tHmh7akuro6POKeme0slDbqRxTMFLMD3+OSZkREdZa6He4Mw8zMts9ONaa3NW7YsGFs3Lhxq7J77rmn/qJ0KW+99RYnn3zyNuXTpk1j3333bdYYzaxtcsLoYJ55pmHvLNnsu+++1NbWNnM0ZjuvDRvKX+NsbHlb5IRhZpaDuq49SmmPl499DcPMzDJxwjAzs0w6XsLwgBhmZtul4yWMlh4Qg7+NF1FZWcknPvEJVq9e3Sxv5a677mL06NEll69YsYJhw4ZRVVXV5L6gdsStt95KRUUFa9asqS979NFH6dq1K1VVVRx22GEcf/zxPPjgg1utd/fdd1NZWUn//v054ogjuPnmm1ssZjNrXMdLGK2gbryIOXPm0L17d3784x+3yH6nTZtGv379mDlz5jZde9SNu5GHCRMmMGTIECZPnrxV+XHHHcfMmTOZP38+Y8eOZfTo0UybNg1IBlK67bbbmDp1KnPnzuW5556ja9euucVoZk3nhNHChg8fzuuvv14//4Mf/IAhQ4YwYMAArr/++vryc845h6OOOor+/fszbty4+vI777yTQw89lBNOOIE///nPJfdTW1vL1VdfzZQpUxg0aBDr16+nS5cujBkzhmHDhvHUU08xbdo0qqqqOPLII7n00kvrn8/o3bs3X/va1xg+fDjV1dU899xznH766XzkIx/hjjvuKPv+Xn75ZdauXcu3vvWtrca+aGjQoEGMGTOG22+/HYB///d/5+abb+bAAw8EoKKigiuuuKLsvsyshWXtB709TFnHw2jpATHqxovYtGlTfOpTn4qHHnooIiIefvjhuOKKK2LLli2xefPmOPPMM+N///d/IyLirbfeioiIdevWRf/+/WPlypWxdOnS6NWrVyxfvjw2btwYxxxzzFZjYzTUcOwMICZNmhQREevXr4+DDjoo5s+fHxERF198cdx6660RkYzf8ZOf/CQiIr74xS/GkUceGe+8804sX748evToUfa93nTTTXHjjTfG5s2b45BDDok333wzIrYd1yMiYubMmdGvX7+IiOjWrVusXr26sUNp1q4UflUse2V9+crrt12+1dfMjg7MUzLGtjEehqXqOufbd999WbVqFaeeeiqQjGUxdepUqqqqGDx4MC+++CILFiwAYOzYsQwcOJCjjz6a1157jQULFvDMM89w4okn0qNHD3bffXc+85nPNCmOTp068clPfhKA+fPn06dPHw499FAARo4cudXwqWeddRaQdJI4bNgw9tprL3r06EFFRUXZazATJ07kggsuYJddduG8887jvvvuK1k32uON6Gbb6e97N3L9tB08xeeE0QLqrmG8+uqrvP/++/XXMCKCa6+9ltraWmpra1m4cCGXXXYZjz76KH/605946qmneP7556mqqmJDejeWyj0J1IiKigo6depUv+9y6sbS2GWXXbYaV2OXXXYpOa7GrFmzWLBgAaeeeiq9e/dm4sSJZZulZs6cyeGHHw5QPzaGmbVduSUMSeMlLZc0p8TyrxaMxDdH0mZJ3dNliyXNTpc1b/ezrTEgRqpr166MHTuWm2++mQ8++IDTTz+d8ePHs3btWgBef/11li9fzpo1a+jWrRt77rknL774Ik8//TSQ9AP16KOP8tZbb/HBBx+U/e+9Mf369WPx4sUsXLgQSPqTOuGEE7Z7e5Bc7L7hhhvqx75YunQpr7/+etGR/mbNmsVNN93EVVcl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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f76330908>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "    \n",
    "X = np.arange(len(values))\n",
    "plt.bar(X + 0.0, values, facecolor='blue', \n",
    "        edgecolor='white', width=0.5, label=\"Written_to_DAC\")\n",
    "plt.bar(X + 0.25, samples, facecolor='red', \n",
    "        edgecolor='white', width=0.5, label=\"Read_from_ADC\")\n",
    "\n",
    "plt.title('DAC-ADC Linearity')\n",
    "plt.xlabel('Sample_number')\n",
    "plt.ylabel('Volts')\n",
    "plt.legend(loc='upper left', frameon=False)\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----\n",
    "\n",
    "[Contents](#Contents)\n",
    "\n",
    "----"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Widget controlled plot\n",
    "\n",
    "In this example, we extend the IO plot with a slider widget to control the number of samples appearing in the output plot.\n",
    "\n",
    "We use the `ipwidgets` library and the simple `interact()` method to launch a slider bar.\n",
    "\n",
    "> The interact function (ipywidgets.interact) automatically creates user interface (UI) controls for exploring code and data interactively. It is the easiest way to get started using IPython’s widgets.\n",
    "\n",
    "For more details see [Using ipwidgets interact()](https://ipywidgets.readthedocs.io/en/latest/examples/Using%20Interact.html#)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "8b03a9cdbde347868797733cd4001629"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from math import ceil\n",
    "from time import sleep\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "from ipywidgets import interact\n",
    "import ipywidgets as widgets\n",
    "\n",
    "ol = BaseOverlay(\"base.bit\")\n",
    "\n",
    "dac = Pmod_DAC(ol.PMODB)\n",
    "adc = Pmod_ADC(ol.PMODA)\n",
    "\n",
    "def capture_samples(nmbr_of_samples):\n",
    "    delay = 0.0\n",
    "    values = np.linspace(0, 2, nmbr_of_samples)\n",
    "    samples = []\n",
    "    for value in values:\n",
    "        dac.write(value)\n",
    "        sleep(delay)\n",
    "        sample = adc.read()\n",
    "        samples.append(sample[0])\n",
    "\n",
    "    X = np.arange(nmbr_of_samples)\n",
    "    plt.bar(X + 0.0, values[:nmbr_of_samples+1], \n",
    "            facecolor='blue', edgecolor='white', \n",
    "            width=0.5, label=\"Written_to_DAC\")\n",
    "    plt.bar(X + 0.25, samples[:nmbr_of_samples+1], \n",
    "            facecolor='red', edgecolor='white', \n",
    "            width=0.5, label=\"Read_from_ADC\")\n",
    "\n",
    "    plt.title('DAC-ADC Linearity')\n",
    "    plt.xlabel('Sample_number')\n",
    "    plt.ylabel('Volts')\n",
    "    plt.legend(loc='upper left', frameon=False)\n",
    "    plt.show()\n",
    "\n",
    "_ = interact(capture_samples, \n",
    "             nmbr_of_samples=widgets.IntSlider(\n",
    "                 min=5, max=30, step=5,\n",
    "                 value=10, continuous_update=False))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----\n",
    "\n",
    "[Contents](#Contents)\n",
    "\n",
    "----"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  },
  "widgets": {
   "state": {
    "c1b64babc85043a38c46fd265c8ac132": {
     "views": [
      {
       "cell_index": 25
      }
     ]
    }
   },
   "version": "1.2.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
